from typing import List, Optional
from bson import ObjectId
from app.models.user import UserInDB
from app.schemas.user import UserCreate, UserUpdate
from app.database.connection import get_database
from passlib.context import CryptContext
from datetime import datetime

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

def verify_password(plain_password, hashed_password):
    return pwd_context.verify(plain_password, hashed_password)

def get_password_hash(password):
    return pwd_context.hash(password)

async def get_user_by_id(user_id: str) -> Optional[UserInDB]:
    """根据ID获取用户"""
    db = get_database()
    user_data = await db["users"].find_one({"_id": ObjectId(user_id)})
    if user_data:
        return UserInDB(**user_data)
    return None

async def get_user_by_username(username: str) -> Optional[UserInDB]:
    """根据用户名获取用户"""
    db = get_database()
    user_data = await db["users"].find_one({"username": username})
    if user_data:
        return UserInDB(**user_data)
    return None

async def get_user_by_email(email: str) -> Optional[UserInDB]:
    """根据邮箱获取用户"""
    db = get_database()
    user_data = await db["users"].find_one({"email": email})
    if user_data:
        return UserInDB(**user_data)
    return None

async def get_users(skip: int = 0, limit: int = 100) -> List[UserInDB]:
    """获取用户列表"""
    db = get_database()
    users_data = await db["users"].find().skip(skip).limit(limit).to_list(length=limit)
    return [UserInDB(**user_data) for user_data in users_data]

async def create_user(user: UserCreate) -> UserInDB:
    """创建新用户"""
    db = get_database()
    user_dict = user.dict()
    user_dict["hashed_password"] = get_password_hash(user_dict.pop("password"))
    user_dict["created_at"] = datetime.utcnow()
    user_dict["updated_at"] = datetime.utcnow()
    
    result = await db["users"].insert_one(user_dict)
    user_dict["_id"] = result.inserted_id
    return UserInDB(**user_dict)

async def update_user(user_id: str, user_update: UserUpdate) -> Optional[UserInDB]:
    """更新用户信息"""
    db = get_database()
    update_data = {k: v for k, v in user_update.dict().items() if v is not None}
    if update_data:
        update_data["updated_at"] = datetime.utcnow()
        result = await db["users"].update_one(
            {"_id": ObjectId(user_id)},
            {"$set": update_data}
        )
        if result.modified_count > 0:
            return await get_user_by_id(user_id)
    return None

async def delete_user(user_id: str) -> bool:
    """删除用户"""
    db = get_database()
    result = await db["users"].delete_one({"_id": ObjectId(user_id)})
    return result.deleted_count > 0

async def authenticate_user(username: str, password: str) -> Optional[UserInDB]:
    """验证用户凭据"""
    user = await get_user_by_username(username)
    if not user:
        return None
    if not verify_password(password, user.hashed_password):
        return None
    return user